package com.fuze.energy.netty.handler;

import com.fuze.energy.utils.MessageConvert;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.util.Map;

/**
 * @author sepc_
 * @date 8/16/2021 15:03
 * Netty Server 处理器
 */
@Slf4j
@Component
public class NettyServerHandler extends SimpleChannelInboundHandler<ByteBuf> {

    public NettyServerHandler() {
    }

    StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf buf) throws Exception {
        try {
            InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
            String ip = inSocket.getAddress().getHostAddress();
            byte[] bytes = new byte[buf.readableBytes()];
            buf.readBytes(bytes, 0, bytes.length);
            String message = MessageConvert.byte2HexStr(bytes, bytes.length);
            log.info("服务端收到客户端[{}]报文：{}", ip, message);
            Map<String, Double> r = MessageConvert.parse(message);
            /*
            使用一个定时任务每隔一段时间从redis中获取数据
            获取的数据构建成entity并持久化保存到数据库中
             */
            /*这里一定一定要设置一个过期时间，否则采集硬件出现问题的情况下很难发觉，因为Redis中始终存在数据*/
            r.forEach((k, v) -> stringRedisTemplate.opsForValue().set(k, String.valueOf(v)));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("报文解析失败，异常：{}", e.getMessage());
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = inSocket.getAddress().getHostAddress();
        log.info("收到客户端[{}]连接", clientIp);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIp = inSocket.getAddress().getHostAddress();
        log.info("客户端[{}]已断开连接", clientIp);
    }
}
